package site.huoqiang.emos.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import site.huoqiang.emos.common.util.PageUtils;
import site.huoqiang.emos.exception.EmosException;
import site.huoqiang.emos.mapper.MeetingMapper;
import site.huoqiang.emos.pojo.Meeting;
import site.huoqiang.emos.service.MeetingService;
import site.huoqiang.emos.task.MeetingWorkflowTask;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author: huoqiang huoqiang
 * @date: 2022-03-03
 */
@Service
@Slf4j
public class MeetingServiceImpl implements MeetingService {

    @Autowired
    private MeetingMapper meetingMapper;

    @Autowired
    private MeetingWorkflowTask meetingWorkflowTask;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询线下会议分页表单
     *
     * @param param
     * @return
     */
    @Override
    public PageUtils searchOfflineMeetingByPage(HashMap param) {
        ArrayList<HashMap> list = meetingMapper.searchOfflineMeetingByPage(param);
        long count = meetingMapper.searchOfflineMeetingCount(param);
        // int start = (int) param.get("start");
        int start = MapUtil.getInt(param, "start");
        int length = MapUtil.getInt(param, "length");
        // 把meeting字段转换成JSON数组对象
        for (HashMap map : list) {
            String meeting = (String) map.get("meeting");
            // 如果Meeting是有效的字符串，就转换成JSON数组对象
            if (meeting != null && meeting.length() > 0) {
                map.replace("meeting", JSONUtil.parseArray(meeting));
            }
        }
        PageUtils pageUtils = new PageUtils(list, count, start, length);
        return pageUtils;
    }

    /**
     * 查询线上会议分页
     *
     * @param param
     * @return
     */
    @Override
    public PageUtils searchOnlineMeetingByPage(HashMap param) {
        ArrayList<HashMap> list = meetingMapper.searchOnlineMeetingByPage(param);
        Long count = meetingMapper.searchOnlineMeetingCount(param);
        int start = (Integer) param.get("start");
        int length = (Integer) param.get("length");
        return new PageUtils(list, count, start, length);
    }

    /**
     * 新增会议申请
     *
     * @param meeting
     * @return
     */
    @Override
    public int insert(Meeting meeting) {
        int row = meetingMapper.insert(meeting);
        if (row != 1) {
            throw new EmosException("会议添加失败");
        }
        meetingWorkflowTask.startMeetingWorkflow(
                meeting.getUuid(),
                meeting.getCreatorId(),
                meeting.getTitle(),
                meeting.getDate(),
                meeting.getStart() + ":00",
                meeting.getType() == 1 ? "线上会议" : "线下会议"
        );
        return row;
    }

    /**
     * 查询线下会议周日历
     *
     * @param param
     * @return
     */
    @Override
    public ArrayList<HashMap> searchOfflineMeetingInWeek(HashMap param) {
        return meetingMapper.searchOfflineMeetingInWeek(param);
    }

    /**
     * 查询线下会议详情
     *
     * @param status
     * @param id
     * @return
     */
    @Override
    public HashMap searchMeetingInfo(short status, long id) {
        // 判断正在进行中的会议
        HashMap map;
        // 正在进行和已经结束的会议都可以查询present和unpresent字段
        if (status == 4 || status == 5) {
            map = meetingMapper.searchCurrentMeetingInfo(id);
        } else {
            map = meetingMapper.searchMeetingInfo(id);
        }
        return map;
    }

    /**
     * 删除会议
     *
     * @param param
     * @return
     */
    @Override
    public int deleteMeetingApplication(HashMap param) {
        Long id = MapUtil.getLong(param, "id");
        String uuid = MapUtil.getStr(param, "uuid");
        String instanceId = MapUtil.getStr(param, "instanceId");

        // 查询会议详情，判断是否距离会议开始不足20分钟
        HashMap meeting = meetingMapper.searchMeetingById(param);
        // 获取会议开始时间和结束时间和状态
        String date = MapUtil.getStr(meeting, "date");
        String start = MapUtil.getStr(meeting, "start");
        int status = MapUtil.getInt(meeting, "status");
        boolean isCreator = Boolean.parseBoolean(MapUtil.getStr(meeting, "isCreator"));

        DateTime dateTime = DateUtil.parse(date + " " + start);
        DateTime now = DateUtil.date();

        //距离会议开始不足20分钟，不能删除会议
        if (now.isAfterOrEquals(dateTime.offset(DateField.MINUTE, -20))) {
            throw new EmosException("距离会议开始不足20分钟，不能删除会议");
        }

        // 只能申请人删除该会议
        if (!isCreator) {
            throw new EmosException("只能申请人删除该会议");
        }

        // 待审批和未开始的会议可以删除
        if (status == 1 || status == 3) {
            int rows = meetingMapper.deleteMeetingApplication(param);
            if (rows == 1) {
                String reason = MapUtil.getStr(param, "reason");
                meetingWorkflowTask.deleteMeetingApplication(uuid, instanceId, reason);
            }
            return rows;
        } else {
            throw new EmosException("只能删除待审批和未开始的会议");
        }
    }

    /**
     * 查询视频会议RoomId
     *
     * @param uuid
     * @return
     */
    @Override
    public Long searchRoomIdByUuid(String uuid) {
        if (redisTemplate.hasKey(uuid)) {
            final Object temp = redisTemplate.opsForValue().get(uuid);
            return Long.parseLong(temp.toString());
        }
        return null;
    }

    /**
     * 查询线上会议成员
     *
     * @param param
     * @return
     */
    @Override
    public ArrayList<HashMap> searchOnlineMeetingMembers(HashMap param) {
        return meetingMapper.searchOnlineMeetingMembers(param);
    }

    /**
     * 查询会议是否可以签到
     *
     * @param param
     * @return
     */
    @Override
    public boolean searchCanCheckMeeting(HashMap param) {
        final Long count = meetingMapper.searchCanCheckMeeting(param);
        return count == 1;
    }

    /**
     * 更新出席人员名单
     *
     * @param param
     * @return
     */
    @Override
    public int updateMeetingPresent(HashMap param) {
        return meetingMapper.updateMeetingPresent(param);
    }
}
